#pragma once
#include <game/Config.h>
#include "ServiceProvider.h"
#include "ScreenBackendFactory.h"
#include <game/flow/SelectorFactory.h>
#include <game/flow/TriggerFactory.h>
#include <game/DebugInfoManager.h>
#include <lib3d/node/Root.h>
#include <game/controls/ControlFactory.h>

#include <xml/Object.h>
#include <filesystem/String.hpp>

namespace liba {
namespace lib3d {
class Application;
} // namespace lib3d
} // namespace liba

ARELLO_GAME_NAMESPACE_DECL_START
namespace flow {
class Manager;
} // namespace flow
namespace controls {
class ControlFactory;
} // namespace controls
class Root;
class ScreenBackendFactory;


/** Data object for storing whole-game related parameters such as
*	screen size and (in the future) root scene name 
*
*	The structure of the xml is following:
*
*	Optional node: Window
*		Required attribute: Width
*		Required attribute: Height
*
*	Required node: MainScreen - should be of type ScreenRef
*/
class GameDefinition
	: private xml::ObjectANSI
{
private:
	virtual bool on_node(xml::Provider * prov, const std::string & name);
public:
	GameDefinition();
	~GameDefinition();

	xml::ObjectANSI* GetLoader() { return this; }

	size_t GetWidth() const { return this->width; }
	size_t GetHeight() const { return this->height; }

	const filesystem::String& GetCursorScenePath() const { return this->cursorScenePath; }

	ScreenBackendFactory& GetBackendFactory() { return this->backendFactory; }
	flow::TriggerFactory& GetTriggerFactory() { return this->triggerFactory; }
	flow::SelectorFactory& GetSelectorFactory() { return this->selectorFactory; }
	ServiceProvider& GetPredefinedServices() { return this->predefinedServices; }
	controls::ControlFactory& GetControlFactory() { return this->controlFactory; }

	std::auto_ptr<Root> CreateRoot(liba::lib3d::Application* app);
private:
	size_t width;
	size_t height;

	std::auto_ptr<flow::Manager> flowManager;
	controls::ControlFactory controlFactory;
	filesystem::String cursorScenePath;
	filesystem::String debugScenePath;
	filesystem::String debugCamera;
	ScreenBackendFactory backendFactory;
	flow::TriggerFactory triggerFactory;
	flow::SelectorFactory selectorFactory;
	ServiceProvider predefinedServices;
	bool debugActivate;
	lib3d::node::Root loadingRoot;	
};	

ARELLO_GAME_NAMESPACE_DECL_END